package com.main.printing;

import java.awt.*;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.util.ArrayList;
import java.util.StringTokenizer;

/**
 * @author Erik Stell
 * @version 1.0
 */
class PagePainter implements Printable {

    private final ArrayList articles;
    private ArrayList pages;
    private PageFormat curPageFormat;
    private final Font font = new Font("TimesRoman", Font.PLAIN, 12);

    /**
     * @param l
     */
    public PagePainter(ArrayList l) {
        articles = l;
    }

    /**
     * @param pf
     * @return
     */
    public int calculatePageCount(PageFormat pf) {
        // calculate pagecount based on pf and articles
        ArrayList pgs = repaginate(pf);
        return pgs.size();
    }

    /**
     * @param g
     * @param pf
     * @param idx
     * @return
     * @throws PrinterException
     */
    public int print(Graphics g, PageFormat pf, int idx)
            throws PrinterException {
        // Printable's method implementation
        if (curPageFormat != pf) {
            curPageFormat = pf;
            pages = repaginate(pf);
        }
        if (idx >= pages.size()) {
            return Printable.NO_SUCH_PAGE;
        }
        g.setFont(font);
        g.setColor(Color.black);
        renderPage(g, pf, idx);
        return Printable.PAGE_EXISTS;
    }

    /**
     * @param pf
     * @return
     */
    ArrayList repaginate(PageFormat pf) {
        // step through articles, creating pages of lines
        int maxh = (int) pf.getImageableHeight();
        int lineh = font.getSize();
        ArrayList pgs = new ArrayList();
        for (Object article : articles) {
            String art = (String) article;
            ArrayList page = new ArrayList();
            int pageh = 0;
            // headers
            page.add(" ");
            pageh += (lineh * 2);
            // body
            StringTokenizer st = new StringTokenizer(art, "\n");
            while (st.hasMoreTokens()) {
                String line = st.nextToken();
                if (pageh + lineh > maxh) {
                    // need new page
                    pgs.add(page);
                    page = new ArrayList();
                    pageh = 0;
                }
                page.add(line);
                pageh += lineh;
            }
            pgs.add(page);
        }
        return pgs;
    }

    /**
     * @param g
     * @param pf
     * @param idx
     */
    void renderPage(Graphics g, PageFormat pf, int idx) {
        // render the lines from the pages list
        int xo = (int) pf.getImageableX();
        int yo = (int) pf.getImageableY();
        int y = font.getSize();
        ArrayList page = (ArrayList) pages.get(idx);
        for (Object aPage : page) {
            String line = (String) aPage;
            g.drawString(line, xo, y + yo);
            y += font.getSize();
        }
    }
}